package com.pangda.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.ArrayUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.pangda.common.domain.PageResult;
import com.pangda.common.domain.ResponseResult;
import com.pangda.common.utils.UserContext;
import com.pangda.mapper.SysRoleMenuMapper;
import com.pangda.pojo.SysRole;
import com.pangda.mapper.SysRoleMapper;
import com.pangda.pojo.SysRoleMenu;
import com.pangda.pojo.dto.SysRoleDto;
import com.pangda.pojo.vo.SysRoleVo;
import com.pangda.service.ISysRoleMenuService;
import com.pangda.service.ISysRoleService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import io.swagger.models.auth.In;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

/**
 * <p>
 * 角色表 服务实现类
 * </p>
 *
 * @author xjy
 * @since 2024-06-20
 */
@Service
public class SysRoleServiceImpl extends ServiceImpl<SysRoleMapper, SysRole> implements ISysRoleService {
    @Autowired
    private SysRoleMapper sysRoleMapper;
    @Autowired
    private ISysRoleMenuService sysRoleMenuService;

    /**
     * 新增角色
     *
     * @param sysRoleDto 角色
     */
    @Override
    @Transactional
    public void addRole(SysRoleDto sysRoleDto) {
        SysRole bean = BeanUtil.toBean(sysRoleDto, SysRole.class);
        bean.setCreateBy(UserContext.getUser());
        bean.setCreateTime(LocalDateTime.now());
        save(bean);
        if (ObjectUtil.isNotEmpty(sysRoleDto.getMenuIds())) {
            List<SysRoleMenu> roleMenus = getSysRoleMenus(sysRoleDto, Math.toIntExact(bean.getRoleId()));
            sysRoleMenuService.saveBatch(roleMenus);
        }
    }

    /**
     * 获取角色菜单
     *
     * @param sysRoleDto 角色
     * @param roleId     角色ID
     * @return 角色菜单
     */
    private static List<SysRoleMenu> getSysRoleMenus(SysRoleDto sysRoleDto, Integer roleId) {
        List<SysRoleMenu> roleMenus = sysRoleDto.getMenuIds().stream().map(menuId -> {
            SysRoleMenu sysRoleMenu = new SysRoleMenu();
            sysRoleMenu.setMenuId(Math.toIntExact(menuId));
            sysRoleMenu.setRoleId(Math.toIntExact(roleId));
            return sysRoleMenu;
        }).collect(Collectors.toList());
        return roleMenus;
    }

    /**
     * 修改角色
     *
     * @param sysRoleDto 角色
     */
    @Override
    @Transactional
    public ResponseResult updateRole(SysRoleDto sysRoleDto) {
        if (sysRoleDto.getRoleId() != null) {
            // 修改角色信息
            sysRoleDto.setUpdateBy(UserContext.getUser());
            sysRoleDto.setUpdateTime(String.valueOf(LocalDateTime.now()));
            updateById(BeanUtil.toBean(sysRoleDto, SysRole.class));
            // 删除该角色所有菜单
            LambdaQueryWrapper<SysRoleMenu> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(SysRoleMenu::getRoleId, sysRoleDto.getRoleId());
            sysRoleMenuService.remove(queryWrapper);
            // 添加角色菜单
            List<SysRoleMenu> roleMenus = getSysRoleMenus(sysRoleDto, Math.toIntExact(sysRoleDto.getRoleId()));
            sysRoleMenuService.saveBatch(roleMenus);
            return ResponseResult.success();
        }
        return ResponseResult.error();
    }

    /**
     * 角色列表
     *
     * @param pageResult 分页
     * @param sysRoleDto 查询条件
     * @return
     */
    @Override
    public PageResult<SysRoleVo> roleList(PageResult pageResult, SysRoleDto sysRoleDto) {
        LambdaQueryWrapper<SysRole> queryWrapper = new LambdaQueryWrapper<>();
        Object beginTime = null;
        Object endTime = null;
        if (ObjectUtil.isNotEmpty(pageResult.getParams())) {
            beginTime = pageResult.getParams().get("beginTime");
            endTime = pageResult.getParams().get("endTime");
        }
        queryWrapper.eq(ObjectUtil.isNotEmpty(sysRoleDto.getStatus()), SysRole::getStatus, sysRoleDto.getStatus())
                .eq(SysRole::getDelFlag, 0)
                .like(ObjectUtil.isNotEmpty(sysRoleDto.getRoleName()), SysRole::getRoleName, sysRoleDto.getRoleName())
                .like(ObjectUtil.isNotEmpty(sysRoleDto.getRoleKey()), SysRole::getRoleKey, sysRoleDto.getRoleKey())
                .between(ObjectUtil.isNotEmpty(beginTime) && ObjectUtil.isNotEmpty(endTime), SysRole::getCreateTime, beginTime, endTime + " 23:59:59");
        Page<SysRole> page = page(new Page<>(pageResult.getPageNum(), pageResult.getPageSize()), queryWrapper);
        List<SysRole> records = page.getRecords();
        List<SysRoleVo> sysRoleVos = BeanUtil.copyToList(records, SysRoleVo.class);
        sysRoleVos.forEach(sysRoleVo -> {
            List<SysRoleMenu> list = sysRoleMenuService.list(new LambdaQueryWrapper<SysRoleMenu>().eq(SysRoleMenu::getRoleId, sysRoleVo.getRoleId()));
            List<Integer> collect = list.stream().map(SysRoleMenu::getMenuId).collect(Collectors.toList());
//            List<String> strings = BeanUtil.copyToList(collect, String.class);
            Integer[] array = ArrayUtil.toArray(collect, Integer.class);
            sysRoleVo.setMenuIds(array);
        });
        PageResult<SysRoleVo> success = PageResult.success(page, SysRoleVo.class);
        success.setRows(sysRoleVos);
        return success;
    }

    /**
     * 角色详情
     *
     * @param roleId 角色id
     * @return
     */
    @Override
    public ResponseResult<SysRoleVo> getRole(Long roleId) {
        SysRoleVo sysRoleVo = new SysRoleVo();
        if (ObjectUtil.isNotEmpty(roleId)) {
            SysRole sysRole = getById(roleId);
            sysRoleVo = BeanUtil.toBean(sysRole, SysRoleVo.class);
            List<SysRoleMenu> list = sysRoleMenuService.list(new LambdaQueryWrapper<SysRoleMenu>().eq(SysRoleMenu::getRoleId, roleId));
            List<Integer> collect = list.stream().map(SysRoleMenu::getMenuId).collect(Collectors.toList());
            Integer[] array = ArrayUtil.toArray(collect, Integer.class);
            sysRoleVo.setMenuIds(array);
        }
        return ResponseResult.success(sysRoleVo);
    }
}
